package richtext

import (
	"strings"
)


type RenderOptionsHtml struct {
	// empty now
}
type RenderOptionsConsole struct {
	AnsiPalette  AnsiPalette
}
func (opts RenderOptionsConsole) WrapSpanContent(content string, tags ([] string)) string {
	if opts.AnsiPalette != nil {
		var buf strings.Builder
		for _, tag := range tags {
			buf.WriteString(opts.AnsiPalette(tag))
		}
		buf.WriteString(content)
		buf.WriteString(reset)
		return buf.String()
	} else {
		return content
	}
}

func (b Block) RenderConsole() string {
	return b.RenderConsoleWithOptions(RenderOptionsConsole{
		AnsiPalette: defaultPalette,
	})
}
func (b Block) RenderPlainText() string {
	return b.RenderConsoleWithOptions(RenderOptionsConsole {})
}

func (b Block) RenderHtmlWithOptions(_ RenderOptionsHtml) Html {
	panic("not implemented")  // TODO
}
func (b Block) RenderConsoleWithOptions(opts RenderOptionsConsole) string {
	if len(b.Lines) == 0 && len(b.Children) == 1 {
		return b.Children[0].RenderConsoleWithOptions(opts)
	}
	return getBlockText(b, false, opts)
}

func getBlockText(b Block, indent bool, opts RenderOptionsConsole) string {
	return withIndention(indent, func() string {
		var buf strings.Builder
		for _, l := range b.Lines {
			for i, span := range l.Spans {
				buf.WriteString(opts.WrapSpanContent(span.Content, span.Tags))
				if (i + 1) < len(l.Spans) {
					var next = l.Spans[(i + 1)]
					if !(strings.HasSuffix(span.Content, " ")) &&
						!(strings.HasPrefix(next.Content, " ")) &&
						next.Content != "," &&
						next.Content != ":" {
						buf.WriteRune(' ')
					}
				}
			}
			if len(l.Spans) > 0 {
				buf.WriteRune('\n')
			}
		}
		var indent_child = (len(b.Lines) > 0)
		for _, child := range b.Children {
			buf.WriteString(getBlockText(child, indent_child, opts))
		}
		return buf.String()
	})
}
func withIndention(indent bool, k func()(string)) string {
	if !(indent) {
		return k()
	}
	const indention = "    "
	var buf strings.Builder
	var lines = strings.Split(k(), "\n")
	for i, line := range lines {
		if i > 0 {
			buf.WriteRune('\n')
		}
		if line != "" {
			buf.WriteString(indention)
		}
		buf.WriteString(line)
	}
	return buf.String()
}


